<?php

class Weixin_native_pay_service extends MY_Service {

    function __construct() {
        parent::__construct();

        $this->load->model("api_log_model");

        $this->_weixin_pay_config = config_item("weixin_pay");
    }

    /**
     * 创建Native支付订单
     */
    function createNativeOrder($description, $orderNo, $amount, $confirmTime) {

        $config = $this->_weixin_pay_config;

        $url = $config["native_pay_url"];
        $data = [
            'mchid' => $config['mchid'],
            'appid' => $config['appid'], // 使用小程序APPID
            'description' => $description,
            'out_trade_no' => $orderNo,
            'notify_url' => WEB_URL . "notifyD/weixin-nativePay-" . $orderNo . "-" . $confirmTime . ".html",
            'amount' => [
                'total' => intval($amount * 100), // 转换为分
                'currency' => 'CNY'
            ]
        ];
        $params = $data;

        $result = $this->postApi($params, "native生成二维码", $url, "post");

        //print_r($result);

        return $result;
        //$headers = $this->generateRequestHeaders(jsonEncode($data, 0), $url, 'POST');
        //$response = $this->httpRequest($url, jsonEncode($data, 0), $headers);
        //$result = jsonDecode($response);
        //print_r($result);
        //return $result['code_url'] ?? false;
    }

    /**
     * 生成带签名的请求头
     */
    function generateRequestHeaders($body, $url, $method) {

        $config = $this->_weixin_pay_config;

        $timestamp = time();
        $nonceStr = bin2hex(random_bytes(16));
        $urlParts = parse_url($url);
        $canonicalUrl = ($urlParts['path'] ?? '/') . (isset($urlParts['query']) ? '?' . $urlParts['query'] : '');

        // 构造签名串
        $signatureStr = sprintf("%s\n%s\n%s\n%s\n%s\n",
                $method,
                $canonicalUrl,
                $timestamp,
                $nonceStr,
                $body
        );

        // 使用商户私钥签名
        $private_key_content = file_get_contents($config['private_key']);
        openssl_sign($signatureStr, $signature, $private_key_content, OPENSSL_ALGO_SHA256);
        $signatureBase64 = base64_encode($signature);

        // 生成Authorization头
        $auth = sprintf('WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",signature="%s",timestamp="%d",serial_no="%s"',
                $config['mchid'],
                $nonceStr,
                $signatureBase64,
                $timestamp,
                $config['serial_no']
        );

        return [
            'Content-Type: application/json',
            'Accept: application/json',
            'Authorization: ' . $auth,
            'User-Agent: MyPayClient/1.0'
        ];
    }

    /**
     * 处理支付回调（使用微信支付公钥验证签名）
     */
    function handlePaymentNotify() {

        $config = $this->_weixin_pay_config;

        // 获取回调数据
        //$headers = getallheaders();
        $headers = jsonDecode('{"Wechatpay-Timestamp":"1748513557","Pragma":"no-cache","Wechatpay-Signature-Type":"WECHATPAY2-SHA256-RSA2048","Wechatpay-Signature":"O4vJLZLQIoeIB3hQD81aov5m1wCUW5OSYhGyFPOEwMtUg70qGpIPGLmzSAVVXUwY\/kwjPA8F\/WAdgSDgsu2VdFZ08UcG3eciZu0Rnn1z0KF1KWfQ3H77DPAQqS8HLB\/dYxuP0suzgtswSL0Cet56xmVWKf3bKhk1ExRbwaclN5mIYMqZcbsRtmlJUjQPf0G6w2bklFFySuomUvHC0k0JZx6HbqZw+ui0k2FlUBJ1lJpWXxRXUAS7MOuIGomlrxjSJfklWii\/GXhj+uw5\/vfNfFPp5RkquPWSBGDiDU5o78PNkduM9VPWQ3fgnS8ouAyhoytUyA8pYW2bjZD4fKsN0g==","Wechatpay-Serial":"2882581E806670C703074C72A3C44E421EECB5BD","Content-Type":"application\/json","Wechatpay-Nonce":"9MzW3LX0lLsUTFydtwgO9AGuCjPcIaTC","Host":"www.matour.com.cn","Accept":"*\/*","User-Agent":"Mozilla\/4.0","Connection":"Keep-Alive","Content-Length":"911"}');

        log_message('error', "微信支付回调->(返回数据)原始=>" . jsonEncode($headers));

        //$body = file_get_contents('php://input');
        $body = '{"id":"5d904828-1af6-5fc3-ad65-e485f6bf76bb","create_time":"2025-05-29T18:12:37+08:00","resource_type":"encrypt-resource","event_type":"TRANSACTION.SUCCESS","summary":"支付成功","resource":{"original_type":"transaction","algorithm":"AEAD_AES_256_GCM","ciphertext":"3XIppRgVtV9K4djjWZyzFwOGfCDco1RXF5x1GBHRpiTX8gvJw18no23BbZMOwDQNVRTYB7LQVDYvxTbp0AZCrfjFb3owq29TfjB+IF0QuZ41p9U2+uNUsLbK7vXOxhh/XCoeZ0lagBzyVZfucsaNut9uWO6C4n5iF4m7bU+RQLsEX2zfv0UUtiwQnivNsgEdr5AVVZEb2p+35zp0oaSLejJTDpamBvqdCEs7iGC21Qu7YkBARvingc9qGsEzWWUWlX7XdvLiwSDuCV27ZSkYmYuVo9owFv5xPde9S0XUiKdxWIcfoR7ofAWLd5/WhOSZt4NHbEfC599/ccX5vjaAV3T9dzpFoQIeRKWRsoqWkBqhBtkjkmQc2yYTImmy5ZsiyouTbawd5vwqtuE2bzc9wf1QRNzlrDYLPY6B4d/mY46mk7jnWX95lsfqAPOCpLqZac6LfahlJR+yetVkxETZfYYOsO9d7Y4muFlBdTASYMylUpka3r8qxB16RDBVDapTL+ihO0CgK8tkSwM9SmLgidz3rlR2Fj+8x6RB6lq/MzHtvQJiPjOuy+j9hudvyp4/pKejfqc=","associated_data":"transaction","nonce":"HI3ORjFnJ4St"}}';

        log_message('error', "微信支付回调->(返回数据)原始=>" . $body);

        // 验证签名
        $signature = $headers['Wechatpay-Signature'] ?? '';
        $timestamp = $headers['Wechatpay-Timestamp'] ?? '';
        $nonce = $headers['Wechatpay-Nonce'] ?? '';
        $serial = $headers['Wechatpay-Serial'] ?? '';

        // 构造签名串
        $signatureStr = "$timestamp\n$nonce\n$body";

        // 使用微信支付公钥验证签名
        $public_key_content = file_get_contents($config['public_key']);
        echo $public_key_content;
        $verified = openssl_verify(
                $signatureStr,
                base64_decode($signature),
                $public_key_content,
                OPENSSL_ALGO_SHA256
        );

        $publicKey = openssl_pkey_get_public(file_get_contents($config['public_key']));
        $result = openssl_verify($signatureStr, base64_decode($signature), $publicKey, OPENSSL_ALGO_SHA256);

        if ($result === 1) {
            echo "✅ 签名验证成功";
        } elseif ($result === 0) {
            echo "❌ 签名不匹配";
        } else {
            echo "🚨 验证错误: " . openssl_error_string();
        }

        if (!openssl_pkey_get_public($public_key_content)) {
            die("Invalid public key: " . openssl_error_string() . "\n");
        }

        if ($verified !== 1) {
            http_response_code(401);
            log_message('error', "微信支付回调->签名验证失败:" . openssl_error_string());
            //error_log("签名验证失败: " . openssl_error_string());
            //exit('签名验证失败');
        }

        // 解密资源数据
        $data = jsonDecode($body);
        $resource = $data['resource'];
        $plaintext = openssl_decrypt(
                base64_decode($resource['ciphertext']),
                'aes-256-gcm',
                $config['api_v3_key'],
                OPENSSL_RAW_DATA,
                base64_decode($resource['nonce']),
                $resource['associated_data']
        );

        if (!$plaintext) {
            http_response_code(400);
            //exit('数据解密失败');
            log_message('error', "微信支付回调->数据解密失败");
        }

        $result = jsonDecode($plaintext);

        log_message('error', "微信支付回调->(返回数据)解析后=>" . $plaintext);

        // 处理支付成功逻辑
        if ($result['trade_state'] === 'SUCCESS') {
            $orderId = $result['out_trade_no'];
            $transactionId = $result['transaction_id'];

//            // TODO: 更新订单状态等业务逻辑
//            file_put_contents('payment.log',
//                    date('[Y-m-d H:i:s] ') . "订单 {$orderId} 支付成功\n",
//                    FILE_APPEND
//            );
            // 返回成功响应
            http_response_code(200);
            echo json_encode(['code' => 'SUCCESS', 'message' => '成功']);
        } else {
            http_response_code(200);
            echo json_encode(['code' => 'FAIL', 'message' => $result['trade_state_desc']]);
        }
    }

    /**
     * HTTP请求函数
     */
    function httpRequest($url, $data = null, $headers = []) {

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);

        if ($data) {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        }

        if ($headers) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }

        $response = curl_exec($ch);

        if (curl_errno($ch)) {
            throw new Exception('Curl error: ' . curl_error($ch));
        }

        curl_close($ch);
        return $response;
    }

    /**
     * 
     */
    public function postApi($params, $item, $url, $method = "post") {

        $request_data = [
            "url" => $url,
            "params" => $params,
        ];

        $paramData = jsonEncode($params);

        $header = $this->generateRequestHeaders($paramData, $url, 'POST');

        $rs = $this->post($url, $paramData, $header, $method);

        $status_code = 0;
        $msg = "失败";
        $data = [];
        $return_code = "";
        $return_msg = "";

        if ($rs["code"] == 200) {
            $sys_data = jsonDecode($rs["data"]);
            if (is_array($sys_data) && !empty($sys_data)) {
                if (isset($sys_data["code_url"]) && $sys_data["code_url"] != "") {
                    $status_code = 1;
                    $msg = "";
                } else {
                    $msg = $sys_data["message"];
                    $return_code = $sys_data["code"];
                    $retrun_msg = $sys_data["message"];
                }
                $data = $sys_data;
            } else {
                $msg = "返回数据格式有误(" . addslashes(htmlspecialchars($rs["data"])) . ")";
            }
        } else {
            $msg = "接口请求失败(" . $rs["data"] . ")";
        }

        $this->api_log_model->addLog(1, "微信支付->" . $item, $request_data, $rs);

        log_message('error', "微信支付->" . $item . "(返回数据)=>" . jsonEncode($rs));

        return [
            "status_code" => $status_code,
            "msg" => $msg,
            "data" => $data,
            "return_code" => $return_code,
        ];
    }

    /*
     * post表单数据
     */

    public function post($url, $postContent = [], $header = null, $method = "post") {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); //连接前等待时间,0不等待
        curl_setopt($ch, CURLOPT_TIMEOUT, 10); //连接后等待时间,0不等待

        if (!empty($header)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        if ($method == "post") {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postContent);
        }

        if (strtolower(substr($url, 0, 5)) == 'https') {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        }

        $code = 200; //执行成功
        $result_data = curl_exec($ch);
        if (curl_errno($ch)) {

            $code = 400; //执行异常
            $result_data = curl_error($ch);
        }
        curl_close($ch);

        //var_dump($result_data);

        return ['code' => $code, 'data' => $result_data];
    }

}
